/*
 * tuple.c
 *
 *  Created on: 19-05-2013
 *      Author: Artur Góralewski
 */

#include "tuple.h"



//function that creates the tuple
//its args are first - is number of elements in the tuple
//the rest of args are elements_of_tuple
tuple* create_tuple(const int amount_args, ...)
{
    int i;
    
	if(amount_args > MAX_SIZE_OF_TUPLE)
		return NULL;

	tuple* new_tuple = (tuple*)malloc(sizeof(tuple));
	
	if (new_tuple == NULL) {
		printf("Przydział pamięci nie udał się\n");
		exit(EXIT_FAILURE);
	}
	
	if (amount_args == 0) {
	    new_tuple->first = NULL;
	    return new_tuple;
	}

	va_list args; //object that contains args
	va_start(args, amount_args);//initialization of object
	element_of_tuple *ptr1, elem = va_arg(args, element_of_tuple);
							//va_arg() - returns next element of args

	new_tuple->first = (element_of_tuple*) malloc (sizeof(element_of_tuple));

    if(new_tuple->first == NULL)
    {
        printf("Przydział pamięci nie udał się\n");
        exit(EXIT_FAILURE);
    }
	new_tuple->first->data = elem.data;
	new_tuple->first->type = elem.type;
	new_tuple->first->next = NULL;

	ptr1 = new_tuple->first;
	
	for(i = 1; i < amount_args; i++)
	{
        elem = va_arg(args, element_of_tuple);
        ptr1->next = (element_of_tuple*) malloc (sizeof(element_of_tuple));
        
        if(ptr1->next == NULL)
        {
	        printf("Przydział pamięci nie udał się\n");
	        exit(EXIT_FAILURE);
        }
        ptr1 = ptr1->next;
        ptr1->data = elem.data;
        ptr1->type = elem.type;
        ptr1->next = NULL;
	}

	va_end(args); //releases dynamically allocated memory that maintains a list of arg

	return new_tuple;
}


//additional function that adds a element to the tuple
void add_elem_to_tuple (tuple *tuplek, const element_of_tuple elem)
{
    element_of_tuple *ptr, *add;
    
    add = (element_of_tuple*)malloc(sizeof(element_of_tuple));
    
    if (add == NULL) {
	    printf("Przydział pamięci nie udał się\n");
	    exit(EXIT_FAILURE);
    }
    add->data = elem.data;
    add->type = elem.type;
    add->next = NULL;
    
    // find a place to insert new node
    ptr = tuplek->first;
    if (ptr == NULL) {
        // tuple empty
        tuplek->first = add;
    } else {
        while (ptr->next != NULL)
            ptr = ptr->next;
        ptr->next = add;
    }
}


//function that prints the tuple
void print_tuple(const tuple *tuplek)
{
    printf("\n## Zawartosc krotki:\n");
    
    element_of_tuple *ptr = tuplek->first;
   
    while( ptr != NULL )
    {
        switch(ptr->type)
        {
	        case STRING :
		        printf("# string: %s\n", ptr->data._string);
		        break;
	        case FLOAT :
		        printf("# float: %f\n", ptr->data._float);
            	break;
	        case INTEGER :
		        printf("# integer: %d\n", ptr->data._integer);
	            break;
        }

        ptr = ptr->next;
    }
    printf("##\n");
}


//function that deletes the tuple
void delete_tuple(tuple *tuplek)
{
     element_of_tuple *ptr=tuplek->first, *temp;
     while( ptr != NULL )
       {
     	temp = ptr->next;
     	free(ptr);
     	ptr = temp;
       }
     free(tuplek);
}

